import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * Created by sheep on 2016/1/3.
 */
public class E17_RadiationCounter {

    public static void main(String[] args) throws Exception {
        ExecutorService exec = Executors.newCachedThreadPool();
        for (int i = 0; i < 1000; i++) {
            exec.execute(new Sensor(i));
        }

        try {
            TimeUnit.SECONDS.sleep(30);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            Sensor.cancel();
            exec.shutdown();
        }
        if (!exec.awaitTermination(250, TimeUnit.MILLISECONDS)) {
            System.out.println("Some task were not termination");
        }
        System.out.println("Total : " + Sensor.getTotalValue());
        System.out.println("sum : " + Sensor.getSumSensor());
    }
}


class Count {
    private int count = 0;
    private Random random = new Random(47);

    public synchronized int increment() {
        int temp = count;
        if (random.nextBoolean()) {
            Thread.yield();
        }
        return (count = ++temp);
    }

    public synchronized int value() {
        return count;
    }
}

class Sensor implements Runnable {
    private static Count count = new Count();
    private static volatile boolean canceled = false;
    public static List<Sensor> sensors = new ArrayList<Sensor>();
    private final int id;
    public int number = 0;

    public Sensor(int id) {
        this.id = id;
        sensors.add(this);
    }

    @Override
    public void run() {
        while (!canceled) {
            synchronized (this) {
                number++;
            }

            //同样的放大并发，注释掉控制台打印。
            count.increment();
            //System.out.println(this + "Total" + count.increment());

            try {
                TimeUnit.MILLISECONDS.sleep(100);
            } catch (InterruptedException e) {
                System.out.println("sleep interrupted");
            }
        }
        System.out.println("Stoping " + this);
    }

    public static boolean cancel() {
        return canceled = true;
    }

    public static int getTotalValue() {
        return count.value();
    }

    public static int getSumSensor() {
        int result = 0;
        for (Sensor sensor : Sensor.sensors) {
            result += sensor.number;
        }
        return result;
    }

    @Override
    public String toString() {
        return "Sensor " + id + " : " + number;
    }
}